import axios, {AxiosRequestConfig} from "axios";

const axiosInstance = axios.create({
  baseURL: 'http://localhost:3000/',
  timeout: 3000
});


interface PendingTask {
  config: AxiosRequestConfig
  resolve: Function
}

// 刷新标记， 如果在刷新，那就返回一个 promise
let refreshing = false;

// 刷新标记返回的resolve方法 和 config 加到队列里
const queue: PendingTask[] = [];

axiosInstance.interceptors.request.use(function (config) {
  const accessToken = localStorage.getItem('access_token');

  if(accessToken) {
    config.headers.authorization = 'Bearer ' + accessToken;
  }
  return config;
})


axiosInstance.interceptors.response.use(
  (response) => {
    return response;
  },
  async (error) => {
    let { data, config } = error.response;

    /**
     * 多个API同时请求时，防止多个refreshToken接口请求
     *
     * token过期，正在刷新 refreshToken
     * 返回一个 promise，并且把它的 resolve 方法还有 config 加到队列里
     */
    if(refreshing) {
      return new Promise((resolve) => {
        queue.push({
          config,
          resolve
        });
      });
    }

    // token 过期
    if (data.statusCode === 401) {
      // refreshing 标记
      refreshing = true;

      // 刷新token
      const res = await refreshToken();

      if(res.status === 200) {

        // refresh 成功，重新发送队列中的请求，并且把结果通过 resolve 返回。
        queue.forEach(({config, resolve}) => {
          resolve(axiosInstance(config))
        })

        return axiosInstance(config);
      } else {
        alert(data || '登录过期，请重新登录');
      }
    } else {
      return error.response;
    }
  }
)



export async function userLogin(username: string, password: string) {
  return await axiosInstance.post('/login', {
    username,
    password
  });
}

async function refreshToken() {
  const res = await axiosInstance.get('/refresh', {
    params: {
      token: localStorage.getItem('refresh_token')
    }
  });
  localStorage.setItem('access_token', res.data.accessToken);
  localStorage.setItem('refresh_token', res.data.refreshToken);
  return res;
}

export async function testApi() {
  return await axiosInstance.get('/test');
}
